bitkeeper revision 1.1159.238.5 (4200df8a5A2pMKPYmS5iOV3Q8d2zIw)
authoriap10@labyrinth.cl.cam.ac.uk <iap10@labyrinth.cl.cam.ac.uk>
Wed, 2 Feb 2005 14:11:22 +0000 (14:11 +0000)
committeriap10@labyrinth.cl.cam.ac.uk <iap10@labyrinth.cl.cam.ac.uk>
Wed, 2 Feb 2005 14:11:22 +0000 (14:11 +0000)
Cset exclude: iap10@labyrinth.cl.cam.ac.uk|ChangeSet|20050202130109|29824

xen/arch/x86/setup.c
xen/common/malloc.c
xen/common/page_alloc.c
xen/include/xen/domain.h
xen/include/xen/lib.h
xen/include/xen/list.h
xen/include/xen/slab.h

index 6d029bed32023bdfcb38e46aaf4a0e4a6b9d9855..f38fc62ff417238bc659bd95d128531a006435e0 100644 (file)
@@ -598,6 +598,10 @@ void __init __start_xen(multiboot_info_t *mbi)
 
     early_boot = 0;
 
+    /* Initialise the slab allocator. */
+    xmem_cache_init();
+    xmem_cache_sizes_init(max_page);
+
     start_of_day();
 
     grant_table_init();
index 9d2750a0d59ccf3152d618494dbb2faf851fe4c6..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 (file)
@@ -1,164 +0,0 @@
-/* Simple allocator for Xen.  If larger than a page, simply use the
- * page-order allocator.
- *
- * Copyright (C) 2005 Rusty Russell IBM Corporation
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#include <xen/mm.h>
-#include <xen/spinlock.h>
-#include <xen/ac_timer.h>
-
-#define BUG_ON(x) do { if (x) BUG(); }while(0)
-
-static LIST_HEAD(freelist);
-static spinlock_t freelist_lock = SPIN_LOCK_UNLOCKED;
-
-struct xmalloc_hdr
-{
-       /* Total including this hdr: negative means allocated. */
-       long size;
-       union {
-               struct list_head freelist;
-               char data[0];
-       } u;
-};
-
-static void maybe_split(struct xmalloc_hdr *hdr, size_t size, size_t block)
-{
-       size_t leftover = block - size;
-
-       /* If enough left to make a block, put it on free list. */
-       if (leftover >= sizeof(struct xmalloc_hdr)) {
-               struct xmalloc_hdr *extra;
-
-               extra = (void *)hdr + size;
-               extra->size = leftover;
-               list_add(&extra->u.freelist, &freelist);
-       } else
-               size = block;
-
-       hdr->size = -size;
-}
-
-static void *xmalloc_new_page(size_t size)
-{
-       struct xmalloc_hdr *hdr;
-       unsigned long flags;
-
-       hdr = (void *)alloc_xenheap_pages(0);
-       if (!hdr)
-               return NULL;
-
-       spin_lock_irqsave(&freelist_lock, flags);
-       maybe_split(hdr, size, PAGE_SIZE);
-       spin_unlock_irqrestore(&freelist_lock, flags);
-       return hdr->u.data;
-}
-
-/* Big object?  Just use page allocator. */
-static void *xmalloc_whole_pages(size_t size)
-{
-       struct xmalloc_hdr *hdr;
-       unsigned int pageorder = get_order(size);
-
-       hdr = (void *)alloc_xenheap_pages(pageorder);
-       if (!hdr)
-               return NULL;
-
-       hdr->size = -(1 << (pageorder + PAGE_SHIFT));
-       return hdr->u.data;
-}
-
-void *__xmalloc(size_t size, const char *file, unsigned int line)
-{
-       struct xmalloc_hdr *i;
-       unsigned long flags;
-
-       /* Add room for header, align to unsigned long. */
-       size += offsetof(struct xmalloc_hdr, u.data);
-       size = ((size + sizeof(unsigned long)-1)&~(sizeof(unsigned long)-1));
-
-       /* Minimum size is size of freelist entry. */
-       if (size < sizeof(*i))
-               size = sizeof(*i);
-
-       /* For big allocs, give them whole pages. */
-       if (size >= PAGE_SIZE)
-               return xmalloc_whole_pages(size);
-
-       /* Search free list */
-       spin_lock_irqsave(&freelist_lock, flags);
-       list_for_each_entry(i, &freelist, u.freelist) {
-               if (i->size >= size) {
-                       list_del(&i->u.freelist);
-                       maybe_split(i, size, i->size);
-                       spin_unlock_irqrestore(&freelist_lock, flags);
-                       return i->u.data;
-               }
-       }
-       spin_unlock_irqrestore(&freelist_lock, flags);
-
-       /* Alloc a new page and return from that. */
-       return xmalloc_new_page(size);
-}
-
-void __xfree(const void *p, const char *file, unsigned int line)
-{
-       unsigned long flags;
-       struct xmalloc_hdr *i, *tmp, *hdr;
-
-       if (!p)
-               return;
-
-       hdr = container_of((void *)p, struct xmalloc_hdr, u.data);
-
-       /* We know hdr will be on same page. */
-       BUG_ON(((long)p & PAGE_MASK) != ((long)hdr & PAGE_MASK));
-
-       /* Not previously freed. */
-       BUG_ON(hdr->size > 0);
-       hdr->size = -hdr->size;
-
-       /* Big allocs free directly. */
-       if (hdr->size >= PAGE_SIZE) {
-               free_xenheap_pages((unsigned long)hdr, get_order(hdr->size));
-               return;
-       }
-
-       /* Merge with other free block, or put in list. */
-       spin_lock_irqsave(&freelist_lock, flags);
-       list_for_each_entry_safe(i, tmp, &freelist, u.freelist) {
-               /* We follow this block?  Swallow it. */
-               if ((void *)i + i->size == (void *)hdr) {
-                       list_del(&i->u.freelist);
-                       i->size += hdr->size;
-                       hdr = i;
-               }
-               /* It follows us?  Delete it and add it to us. */
-               if ((void *)hdr + hdr->size == (void *)i) {
-                       list_del(&i->u.freelist);
-                       hdr->size += i->size;
-               }
-       }
-
-       /* Did we free entire page? */
-       if (hdr->size == PAGE_SIZE) {
-               BUG_ON((((unsigned long)hdr) & (PAGE_SIZE-1)) != 0);
-               free_xenheap_pages((unsigned long)hdr, 0);
-       } else
-               list_add(&hdr->u.freelist, &freelist);
-       spin_unlock_irqrestore(&freelist_lock, flags);
-}
index 147117007949abe606dabbffcf626a5980d9fc3f..eae1692eb1b37c0b927b2736a6f835198cc2ea3d 100644 (file)
@@ -403,8 +403,9 @@ unsigned long alloc_xenheap_pages(unsigned int order)
 {
     unsigned long flags;
     struct pfn_info *pg;
-    int i;
+    int i, attempts = 0;
 
+ retry:
     local_irq_save(flags);
     pg = alloc_heap_pages(MEMZONE_XEN, order);
     local_irq_restore(flags);
@@ -424,7 +425,14 @@ unsigned long alloc_xenheap_pages(unsigned int order)
     return (unsigned long)page_to_virt(pg);
 
  no_memory:
+    if ( attempts++ < 8 )
+    {
+        xmem_cache_reap();
+        goto retry;
+    }
+
     printk("Cannot handle page request order %d!\n", order);
+    dump_slabinfo();
     return 0;
 }
 
index d502f188713a5a0d581ec2830b5075342938f737..c2d0dbc1448390ed085370fa17cca1b4d7f3c3ff 100644 (file)
@@ -6,6 +6,8 @@
  * Arch-specifics.
  */
 
+extern void domain_startofday(void);
+
 extern struct domain *arch_alloc_domain_struct(void);
 
 extern void arch_free_domain_struct(struct domain *d);
index c6f45580d8bf03b3a9029b37476b63aeabb4f4b1..6ce764b7fc7be8cc70de83b069c8341781c2b163 100644 (file)
@@ -20,18 +20,6 @@ struct domain;
 
 void cmdline_parse(char *cmdline);
 
-/**
- * container_of - cast a member of a structure out to the containing structure
- *
- * @ptr:       the pointer to the member.
- * @type:      the type of the container struct this is embedded in.
- * @member:    the name of the member within the struct.
- *
- */
-#define container_of(ptr, type, member) ({                     \
-        const typeof( ((type *)0)->member ) *__mptr = (ptr);   \
-        (type *)( (char *)__mptr - offsetof(type,member) );})
-
 #define printk printf
 void printf(const char *format, ...);
 void panic(const char *format, ...);
index 93d9f987e762b3a9b132c90bd6c62dd06bebbd57..7b19bb4650bbca57853c8420a5af4a31bf984b68 100644 (file)
@@ -174,17 +174,5 @@ static __inline__ void list_splice(struct list_head *list, struct list_head *hea
             pos = list_entry(pos->member.next, typeof(*pos), member),  \
                     prefetch(pos->member.next))
 
-/**
- * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
- * @pos:       the type * to use as a loop counter.
- * @n:         another type * to use as temporary storage
- * @head:      the head for your list.
- * @member:    the name of the list_struct within the struct.
- */
-#define list_for_each_entry_safe(pos, n, head, member)                 \
-       for (pos = list_entry((head)->next, typeof(*pos), member),      \
-               n = list_entry(pos->member.next, typeof(*pos), member); \
-            &pos->member != (head);                                    \
-            pos = n, n = list_entry(n->member.next, typeof(*n), member))
 #endif /* _LINUX_LIST_H */
 
index 8fed6444ff03252a78001771e9b1ecac984b1cf8..25406617dcbb2eb0d6f4420ced1846919a68200d 100644 (file)
 #include <asm/slab.h>
 
 #else
+
+typedef struct xmem_cache_s xmem_cache_t;
+
 #include <xen/mm.h>
 #include <xen/cache.h>
 #include <xen/types.h>
 
-#define _xmalloc(size) __xmalloc(size, __FILE__, __LINE__)
-#define xfree(ptr) __xfree(ptr, __FILE__, __LINE__)
-extern void *__xmalloc(size_t size, const char *file, unsigned int line);
-extern void __xfree(const void *p, const char *file, unsigned int line);
+/* Flags to pass to xmem_cache_create(). */
+/* NB. The first 3 are only valid when built with SLAB_DEBUG_SUPPORT. */
+#define SLAB_DEBUG_INITIAL      0x00000200UL    /* Call constructor */
+#define SLAB_RED_ZONE           0x00000400UL    /* Red zone objs in a cache */
+#define SLAB_POISON             0x00000800UL    /* Poison objects */
+#define SLAB_NO_REAP            0x00001000UL    /* never reap from the cache */
+#define SLAB_HWCACHE_ALIGN      0x00002000UL    /* align obj on a cache line */
+
+/* Flags passed to a constructor function. */
+#define SLAB_CTOR_CONSTRUCTOR   0x001UL /* if not set, then deconstructor */
+#define SLAB_CTOR_ATOMIC        0x002UL /* tell cons. it can't sleep */
+#define SLAB_CTOR_VERIFY        0x004UL /* tell cons. it's a verify call */
+
+extern void xmem_cache_init(void);
+extern void xmem_cache_sizes_init(unsigned long);
+
+extern xmem_cache_t *xmem_find_general_cachep(size_t);
+extern xmem_cache_t *xmem_cache_create(
+    const char *, size_t, size_t, unsigned long,
+    void (*)(void *, xmem_cache_t *, unsigned long),
+    void (*)(void *, xmem_cache_t *, unsigned long));
+extern int xmem_cache_destroy(xmem_cache_t *);
+extern int xmem_cache_shrink(xmem_cache_t *);
+extern void *xmem_cache_alloc(xmem_cache_t *);
+extern void xmem_cache_free(xmem_cache_t *, void *);
+
+extern void *_xmalloc(size_t);
+extern void xfree(const void *);
+
+extern int xmem_cache_reap(void);
+
+extern void dump_slabinfo();
 
 /* Nicely typesafe for you. */
 #define xmalloc(type) ((type *)_xmalloc(sizeof(type)))